// const path = require('path')
// const fs = require('fs-extra')
// const { execFile } = require('child_process')
// const logger = require('./logger')
// const config = require('./config')

// class DocConverter {
//   constructor(inputDir, outputDir) {
//     this.inputDir = path.resolve(inputDir)
//     this.outputDir = path.resolve(outputDir)
//     this.stats = { total: 0, success: 0, failed: 0 }
//   }

//   async run() {
//     try {
//       // 验证输入目录
//       if (!(await fs.pathExists(this.inputDir))) {
//         throw new Error(`输入目录不存在: ${this.inputDir}`)
//       }

//       // 创建输出目录
//       await fs.ensureDir(this.outputDir)
      
//       // 开始转换流程
//       logger.info(`开始转换: ${this.inputDir} → ${this.outputDir}`)
//       await this.processDirectory(this.inputDir)
      
//       // 输出统计结果
//       logger.success(`转换完成! 成功: ${this.stats.success}/${this.stats.total}`)
//       if (this.stats.failed > 0) {
//         logger.warn(`失败文件: ${this.stats.failed}`)
//       }
//     } catch (err) {
//       logger.error(`致命错误: ${err.message}`)
//       process.exit(1)
//     }
//   }

//   async processDirectory(currentDir) {
//     const entries = await fs.readdir(currentDir, { withFileTypes: true })
    
//     for (const entry of entries) {
//       const srcPath = path.join(currentDir, entry.name)
//       const relativePath = path.relative(this.inputDir, srcPath)
//       const destPath = path.join(this.outputDir, relativePath)

//       if (entry.isDirectory()) {
//         // 递归处理子目录
//         await this.processDirectory(srcPath)
//       } else if (this.isWordFile(entry.name)) {
//         // 处理Word文件
//         await this.convertFile(srcPath, destPath)
//       }
//     }
//   }

//   isWordFile(filename) {
//     const ext = path.extname(filename).toLowerCase()
//     return config.extensions.includes(ext)
//   }

//   async convertFile(inputPath, outputPath) {
//     this.stats.total++
//     const mdPath = outputPath.replace(/\.[^/.]+$/, '.md')

//     try {
//       logger.fileStatus(inputPath, 'converting')
      
//       // 确保输出目录存在
//       await fs.ensureDir(path.dirname(mdPath))
      
//       // 执行Pandoc转换
//       await this.runPandoc(inputPath, mdPath)
      
//       this.stats.success++
//       logger.fileStatus(inputPath, 'success')
//     } catch (err) {
//       this.stats.failed++
//       logger.fileStatus(inputPath, 'failed')
//       logger.error(`${path.basename(inputPath)} 转换失败: ${err.message}`)
//     }
//   }

//   runPandoc(inputFile, outputFile) {
//     return new Promise((resolve, reject) => {
//       const args = [
//         inputFile,
//         '-o', outputFile,
//         ...config.pandoc.args
//       ]

//       const child = execFile('pandoc', args, (error) => {
//         error ? reject(error) : resolve()
//       })

//       // 设置超时
//       child.timeout = config.pandoc.timeout
//       child.on('timeout', () => {
//         child.kill()
//         reject(new Error(`转换超时 (${config.pandoc.timeout}ms)`))
//       })
//     })
//   }
// }

// module.exports = DocConverter
const path = require('path')
const fs = require('fs-extra')
const { execFile } = require('child_process')
const logger = require('./logger')
const config = require('./config')

class DocxConverter {
  constructor(inputDir, outputDir) {
    this.inputDir = path.resolve(inputDir)
    this.outputDir = path.resolve(outputDir)
    this.mediaRoot = path.join(this.outputDir, config.mediaDir)
    this.stats = { total: 0, success: 0, failed: 0 }
    this.filterPath = path.resolve(__dirname, 'filters/img-filter.lua')
  }

  // === 主运行方法 ===
  async run() {
    try {
      await this.validatePaths()
      await this.prepareDirectories()
      await this.processDirectory(this.inputDir, 0)
      this.showSummary()
    } catch (err) {
      logger.error(`运行失败: ${err.message}`)
      process.exit(1)
    }
  }

  // === 核心方法 ===

  // 验证路径有效性
  async validatePaths() {
    if (!(await fs.pathExists(this.inputDir))) {
      throw new Error(`输入目录不存在: ${this.inputDir}`)
    }
    if (path.relative(this.inputDir, this.outputDir) === '') {
      throw new Error('输入目录和输出目录不能相同')
    }
  }

  // 准备目录结构
  async prepareDirectories() {
    await fs.ensureDir(this.outputDir)
    await fs.ensureDir(this.mediaRoot)
    logger.info(`创建媒体目录: ${this.mediaRoot}`)
  }

  // 递归处理目录
  async processDirectory(currentDir, depth) {
    if (depth > config.maxDepth) {
      logger.warn(`达到最大目录深度限制 (${config.maxDepth})，停止处理: ${currentDir}`)
      return
    }

    const entries = await fs.readdir(currentDir, { withFileTypes: true })
    
    for (const entry of entries) {
      const srcPath = path.join(currentDir, entry.name)
      const relativePath = path.relative(this.inputDir, srcPath)
      const destPath = path.join(this.outputDir, relativePath)

      if (entry.isDirectory()) {
        await this.processDirectory(srcPath, depth + 1)
      } else if (this.isDocxFile(entry.name)) {
        await this.convertFile(srcPath, destPath)
      }
    }
  }

  // === 文件转换方法 ===

  // 判断是否为DOCX文件
  isDocxFile(filename) {
    return path.extname(filename).toLowerCase() === '.docx'
  }
// 生成媒体子目录路径
getMediaSubDir(inputPath) {
    const relativePath = path.relative(this.inputDir, path.dirname(inputPath))
    
    switch(config.media.structure) {
      case 'mirror':
        return relativePath // 保持与源文件相同的目录结构
      case 'flat':
        return ''          // 所有图片放根目录
      case 'date':
        return new Date().toISOString().slice(0, 10) // 按日期分类
      default:
        return ''
    }
  }

  // 增强版路径清洗
//   cleanPaths(content, mdDir) {
//     return content.replace(/!\[(.*?)\]\((.*?)\)/g, (match, altText, imgPath) => {
//       // 处理绝对路径
//       if (path.isAbsolute(imgPath)) {
//         const relativePath = path.relative(mdDir, imgPath)
//         return `![${altText}](${this.normalizePath(relativePath)})`
//       }
      
//       // 处理嵌套媒体目录
//       const cleanPath = imgPath
//         .replace(/^media[\\/]+/, '')  // 去除开头的media/
//         .replace(/\\/g, '/')          // 统一正斜杠

//       return `![${altText}](${cleanPath})`
//     })
//   }

  // 路径标准化
  normalizePath(p) {
    return p
      .replace(/\\/g, '/')
      .replace(/\/{2,}/g, '/') // 去除重复斜杠
      .replace(/^\.\//, '')    // 去除开头的./
  }
//   async convertFile(inputPath, outputPath) {
//     // 生成相对媒体目录路径
//     const mediaSubDir = path.relative(
//       this.outputDir, 
//       path.dirname(outputPath)
//     ).replace(/\\/g, '/')

//     const args = [
//       inputPath,
//       '-o', mdPath,
//       `--extract-media=${path.join(this.mediaRoot, mediaSubDir)}`, // [!code ++]
//       ...config.pandoc.baseArgs
//     ]
//   }

  cleanPaths(content, mdDir) {
    return content.replace(/!\[\]\((.*?)\)/g, (match, imgPath) => {
      // 移除绝对路径前缀
      const absPrefix = path.resolve(this.mediaRoot) + path.sep
      const cleanPath = imgPath
        .replace(absPrefix, '')
        .replace(/\\/g, '/')
        .replace(/\/+/g, '/')

      // 生成相对路径
      const targetPath = path.join(this.mediaRoot, cleanPath)
      const relativePath = path.relative(mdDir, targetPath)
        .replace(/\\/g, '/')

      return `![](/${relativePath})` // 添加前导斜杠确保相对根目录
    })
  }
  // 执行文件转换
  async convertFile(inputPath, outputPath) {
    // 生成媒体子目录
    // const mediaSubDir = this.getMediaSubDir(inputPath)
    // 生成相对媒体目录路径
    const mediaSubDir = path.relative(
        this.outputDir, 
        path.dirname(outputPath)
      ).replace(/\\/g, '/')
      // 生成正确的媒体目录路径
    const mediaTarget = path.join(
        path.dirname(outputPath), // [!code focus]
        config.mediaDir
    )
    // const mediaTarget = path.join(this.mediaRoot, mediaSubDir)

    this.stats.total++
    const mdPath = outputPath.replace(/\.docx$/, '.md')
    const mediaDir = path.join(path.dirname(mdPath), config.mediaDir)

    try {
      logger.fileStatus(inputPath, 'converting')
      await fs.ensureDir(path.dirname(mdPath))
      
    //   const args = [
    //     inputPath,
    //     '-o', mdPath,
    //     `--extract-media=${this.mediaRoot}`,
    //     ...config.pandoc.baseArgs
    //   ]
    // const args = [
    //     inputPath,
    //     '-o', mdPath,
    //     `--extract-media=${path.relative(process.cwd(), this.mediaRoot)}`, // [!code ++]
    //     ...config.pandoc.baseArgs
    // ]
    // const args = [
    //     inputPath,
    //     '-o', mdPath,
    //     `--extract-media=${mediaTarget}`, // [!code ++]
    //     ...config.pandoc.baseArgs
    // ]
    const args = [
        inputPath,
        `--extract-media=${mediaTarget}`, 
        `--lua-filter=${this.filterPath}`, 
        '-o', mdPath,
        // `--extract-media=${path.join(this.mediaRoot, mediaSubDir)}`, // [!code ++]
        ...config.pandoc.baseArgs
    ]

      await this.execPandoc(args)
      await this.fixImagePaths(mdPath, mediaDir)
      
      this.stats.success++
      logger.fileStatus(inputPath, 'success')
    } catch (err) {
      this.stats.failed++
      logger.fileStatus(inputPath, 'failed')
      logger.error(`转换失败: ${err.message}`)
    }
  }

  // === 辅助方法 ===

  // 执行Pandoc命令
  async execPandoc(args) {
    return new Promise((resolve, reject) => {
      const child = execFile('pandoc', args, (error, stdout, stderr) => {
        if (error) {
          error.message += `\nPandoc错误输出: ${stderr}`
          return reject(error)
        }
        resolve()
      })

      // 设置超时
      child.timeout = config.pandoc.timeout
      child.on('timeout', () => {
        child.kill()
        reject(new Error(`转换超时 (${config.pandoc.timeout}ms)`))
      })
    })
  }

  // 修正图片路径
//   async fixImagePaths(mdPath, mediaDir) {
//     try {
//       let content = await fs.readFile(mdPath, 'utf8')
      
//       // 统一路径格式
//       content = content.replace(/\\/g, '/')
      
//       // 计算相对路径
//       const relativeMedia = path.relative(path.dirname(mdPath), this.mediaRoot)
//         .replace(/\\/g, '/') // Windows路径转换

//       // 正则替换图片路径
//       content = content.replace(
//         /!\[(.*?)\]\((.*?)\)/g, 
//         (match, altText, imgPath) => {
//           // 跳过网络图片
//           if (/^(https?:)?\/\//.test(imgPath)) return match
          
//           // 处理相对路径
//           const fullPath = path.join(relativeMedia, imgPath)
//           return `![${altText}](${fullPath})`
//         }
//       )

//       await fs.writeFile(mdPath, content)
//     } catch (err) {
//       logger.error(`路径修正失败: ${mdPath} - ${err.message}`)
//     }
//   }
async fixImagePaths(mdPath) {
    // try {
    //   let content = await fs.readFile(mdPath, 'utf8')
    //   const mdDir = path.dirname(mdPath)
      
    //   // 深度清理路径
    //   content = this.cleanPaths(content, mdDir)
      
    //   await fs.writeFile(mdPath, content)
    // } catch (err) {
    //   logger.error(`路径修正失败: ${mdPath} - ${err.message}`)
    // }
    const mdDir = path.dirname(mdPath)
    const mediaDir = path.join(mdDir, config.mediaDir)
    
    let content = await fs.readFile(mdPath, 'utf8')
    content = content.replace(/!\[\]\((.*?)\)/g, (match, imgPath) => {
      // 计算相对路径 [!code focus]
      const absPath = path.join(mediaDir, imgPath)
      const relPath = path.relative(mdDir, absPath)
      return `![](${relPath.replace(/\\/g, '/')})`
    })
    
    await fs.writeFile(mdPath, content)
}
cleanPaths(content, mdDir) {
    // 统一路径分隔符
    let cleaned = content.replace(/\\+/g, '/')

    // 匹配所有图片引用
    return cleaned.replace(/!\[(.*?)\]\((.*?)\)/g, (match, altText, imgPath) => {
      // 跳过网络图片
      if (/^(https?:)?\/\//.test(imgPath)) return match
      
      // 获取规范化的相对路径
      const properPath = this.getProperPath(mdDir, imgPath)
      
      return `![${altText}](${properPath})`
    })
}

getProperPath(mdDir, originalPath) {
    const pathStrategies = {
      relative: () => {
        const absPath = path.resolve(this.mediaRoot, originalPath)
        return path.relative(mdDir, absPath)
      },
      absolute: () => path.resolve(this.mediaRoot, originalPath),
      shortest: () => {
        const relPath = path.relative(mdDir, path.resolve(this.mediaRoot, originalPath))
        const absPath = path.resolve(this.mediaRoot, originalPath)
        return relPath.length < absPath.length ? relPath : absPath
      }
    }

    let finalPath = pathStrategies[config.path.strategy]()
    
    // 统一分隔符
    finalPath = finalPath.replace(/\\/g, config.path.separator)
    
    // 处理上层目录访问
    if (finalPath.startsWith('..')) {
      return config.path.allowParentDirs ? finalPath : originalPath
    }
    
    return finalPath
}
  // 显示统计信息
  showSummary() {
    logger.success(`
    转换完成!
    ┌────────────┬─────────┐
    │ 总文件数   │ ${this.stats.total.toString().padEnd(7)} │
    ├────────────┼─────────┤
    │ 成功转换   │ ${this.stats.success.toString().padEnd(7)} │
    ├────────────┼─────────┤
    │ 转换失败   │ ${this.stats.failed.toString().padEnd(7)} │
    └────────────┴─────────┘
    `)
    
    if (this.stats.failed > 0) {
      logger.warn('部分文件转换失败，建议：\n1. 检查原始文件格式\n2. 确认文件没有密码保护\n3. 尝试手动转换失败文件')
    }
  }
}

module.exports = DocxConverter